﻿using AutoControlSpectrum.Device;
using AutoControlSpectrum.EnumHelp;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using AutoControlSpectrum.Extensions;
using AutoControlSpectrum.Model;

namespace AutoControlSpectrum.Manufacturer
{
    /// <summary>
    /// 设备控制
    /// </summary>
    internal class DeviceControl
    {
        private static readonly DeviceControl instance = new DeviceControl();

        /// <summary>
        /// 私有构造函数，防止实例化
        /// </summary>
        private DeviceControl()
        { }

        /// <summary>
        /// 公共静态方法，返回唯一的实例
        /// </summary>
        public static DeviceControl Instance => instance;

        /// <summary>
        /// 消息回调
        /// </summary>
        public Action<string> MsgCallback = (a) => { };

        /// <summary>
        /// 逻辑流程字典
        /// </summary>
        public readonly Dictionary<LogicFlowStep, int> logicFlowDic = new Dictionary<LogicFlowStep, int>
        {
            { LogicFlowStep.DeviceScanBackground, AppSettings.Instance.Bjsmddsc },
            { LogicFlowStep.DeviceScanStart, AppSettings.Instance.Bjsmddsc },
            { LogicFlowStep.SampleSelectSample, AppSettings.Instance.Szypddsc },
            { LogicFlowStep.SampleCalculateSample, AppSettings.Instance.Jsddsc },
            { LogicFlowStep.SampleCalculateResult, 2 },
            { LogicFlowStep.DeleteTreeNode, 2 }
        };

        /// <summary>
        /// 当前状态
        /// </summary>
        private LogicFlowStep? currentState;

        /// <summary>
        /// 是否初始化过
        /// </summary>
        internal bool initialized { get; set; } = false;

        /// <summary>
        /// 样品编号
        /// </summary>
        public string SampleNo { get; private set; }

        /// <summary>
        /// 重置状态
        /// </summary>
        internal void Reset()
        {
            currentState = null;
        }

        /// <summary>
        /// 开始测试
        /// </summary>
        /// <param name="sampleNo">样品编号</param>
        /// <returns></returns>
        internal bool BeginTest(string sampleNo)
        {
            SampleNo = sampleNo;
            if (currentState.HasValue)
            {
                return false;
            }
            _ = ExecuteLogicFlowAsync();

            return true;
        }

        /// <summary>
        /// 是否存在实验
        /// </summary>
        /// <returns></returns>
        internal bool IsExistSample => currentState.HasValue;

        /// <summary>
        /// 手动控制设备
        /// </summary>
        /// <param name="logicFlowStep"></param>
        /// <returns></returns>
        internal async Task HeadConterol(LogicFlowStep logicFlowStep, string cmd)
        {
            MsgCallback($"{DateTime.Now:MM-dd HH:mm:ss}，{cmd}开始执行");
            currentState = logicFlowStep;
            await SendToAllClients(logicFlowStep);

            logicFlowDic.TryGetValue(logicFlowStep, out int value);
            await Task.Delay(TimeSpan.FromSeconds(value));

            MsgCallback($"{DateTime.Now:MM-dd HH:mm:ss}，{cmd}执行结束");
            currentState = null;
        }

        /// <summary>
        /// 执行逻辑流程
        /// </summary>
        /// <returns></returns>
        private async Task ExecuteLogicFlowAsync()
        {
            if (!initialized)
            {
                currentState = LogicFlowStep.DeviceScanBackground;
                initialized = true;
            }
            else
            {
                currentState = LogicFlowStep.DeviceScanStart;
            }
            // 不测试背景
            currentState = LogicFlowStep.DeviceScanStart;

            while (currentState.HasValue)
            {
                var flowStep = currentState.Value;
                MsgCallback($"{DateTime.Now:MM-dd HH:mm:ss}，开始执行：{flowStep}，样品条码：{SampleNo}");

                // 发送当前步骤的命令
                await SendToAllClients(flowStep);

                // 等待指定时间
                await Task.Delay(TimeSpan.FromSeconds(logicFlowDic[flowStep]));

                if (flowStep == logicFlowDic.Last().Key)
                {
                    if (flowStep == LogicFlowStep.DeleteTreeNode)
                    {
                        WindowHelper windowHelper = new WindowHelper("删除光谱", 2);
                        windowHelper.ClickButton("确定", 2);
                    }
                    currentState = null; // 结束流程
                }
                else
                {
                    currentState++;
                }
            }
        }

        private async Task SendToAllClients(LogicFlowStep cmd)
        {
            //if (LogicFlowStep.DeviceRestart == cmd)
            //{
            //    numberOfExecutions = 0;

            //    MsgCallback($"{DateTime.Now:MM-dd HH:mm:ss}，开始重启客户端");

            //    _ = Task.Run(() =>
            //     {
            //         WindowHelper windowHelper2 = new WindowHelper("保存选项", 3);
            //         windowHelper2.ClickButton("确定", 3);
            //     });

            //    _ = Task.Run(() =>
            //    {
            //        WindowHelper windowHelper2 = new WindowHelper("PerkinElmer Spectrum IR", 2);
            //        windowHelper2.CloseWindow();
            //    });

            //    await Task.Delay(TimeSpan.FromSeconds(2));

            //    // 杀死进程
            //    ProcessHelper.KillProcessByName("IRWinLab");
            //    ProcessHelper.KillProcessByName("InstCtrl");
            //    await Task.Delay(TimeSpan.FromSeconds(2));

            //    // 启动程序
            //    ProcessHelper.StartProcess("C:\\Program Files (x86)\\PerkinElmer-bak\\Spectrum\\IRWinLab.exe");

            //    // 点击确定
            //    WindowHelper windowHelper = new WindowHelper("PerkinElmer 登录");
            //    windowHelper.ClickButton("确定");
            //    await Task.Delay(TimeSpan.FromSeconds(25));
            //}
            //else
            //{
            //    SocketServer.Instance.SendToAllClients(cmd.ToString());
            //}
            SocketServer.Instance.SendToAllClients(cmd.ToString() + "(:)" + AppSettings.Instance.MacroId);
            await Task.Delay(TimeSpan.FromMilliseconds(10));
        }
    }
}